package cn.com.jinhao.provider.business.service.impl;

import cn.com.jinhao.hotline.commons.base.constant.SystemConstant;
import cn.com.jinhao.hotline.commons.exception.BusinessErrorException;
import cn.com.jinhao.hotline.commons.util.ExeclUtil;
import cn.com.jinhao.hotline.commons.vo.AttachRequestVO;
import cn.com.jinhao.hotline.commons.vo.business.RecordInfoRequestVO;
import cn.com.jinhao.hotline.commons.vo.business.feedback.FeedbackCondition;
import cn.com.jinhao.hotline.commons.vo.business.feedback.FeedbackRequestVO;
import cn.com.jinhao.provider.business.entity.Feedback;
import cn.com.jinhao.provider.business.mapper.FeebackMapper;
import cn.com.jinhao.provider.business.service.AttachService;
import cn.com.jinhao.provider.business.service.FeedbackService;
import cn.com.jinhao.provider.business.service.RecordInfoService;
import cn.com.jinhao.provider.business.service.WorkflowService;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * HotLine
 * <p>Description: 反馈业务逻辑实现类</p>
 *
 * @author ShaneMew
 * @version 1.0
 * @date 2020/05/30
 * @since 2020/05/30
 */
@Service
public class FeedbackServiceImpl extends CommonService implements FeedbackService {
    @Resource
    FeebackMapper feebackMapper;
    @Resource
    AttachService attachService;
    @Resource
    WorkflowService workflowService;
    @Resource
    RecordInfoService recordInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(FeedbackRequestVO feedbackRequestVO) throws Exception {
        Feedback feedback = new Feedback();
        BeanUtil.copyProperties(feedbackRequestVO, feedback);

        String code = getCode(SystemConstant.CodeType.COMPLEX) + feedback.getEventCode();

        // 根据任务状态接口来判断是否可以反馈
        String statusCode = workflowService.queryStatu(feedback.getEventCode(), feedback.getDispatchCode());
        if (!SystemConstant.FlowStatus.DISPATCH.getStatusCode().equals(statusCode)) {
            String statusName = "";
            for(SystemConstant.FlowStatus e:SystemConstant.FlowStatus.values()) {
                if (e.getStatusCode().equals(statusCode)) {
                    statusName = e.getStatus();
                }
            }
            throw new BusinessErrorException("该订单状态为" + statusName + "，反馈失败！");
        }
        // 生成数据快照
        feedback.setEventFeedback(getDetailMsg(feedback.getFeedbackDept(), feedback.getFeedbackOperator(), feedback.getEventCode(), feedback.getDispatchCode()));
        feedback.setCode(code);
        feedback.setVersion(1);
        int result = feebackMapper.insertSelective(feedback);
        if (result == 0) {
            throw new BusinessErrorException("反馈新增失败");
        }

        // 附件表插入
        List<AttachRequestVO> attachRequestVOS = feedbackRequestVO.getAttachList();

        attachRequestVOS.forEach(item -> item.setHostCode(code));

        attachService.addBatch(attachRequestVOS);

        // 事件表的是否反馈更新为已反馈
        RecordInfoRequestVO recordInfoRequestVO = new RecordInfoRequestVO();
        recordInfoRequestVO.setCode(feedback.getEventCode());
        recordInfoRequestVO.setIsFeedback((short)1);
        //事件状态变更为待办结
        recordInfoRequestVO.setEventStatusCode(SystemConstant.FlowStatus.FINISH.getStatusCode());
        recordInfoRequestVO.setEventStatus(SystemConstant.FlowStatus.FINISH.getStatus());
        recordInfoService.update(recordInfoRequestVO);

        //TODO: 更新流程状态,更新为反馈待审核  SystemConstant.FlowStatus.FEEDBACK_REVIEW.getStatusCode()
    }

    @Override
    public void update(FeedbackRequestVO feedbackRequestVO) throws Exception {
        //TODO： 业务逻辑
        Feedback feedback = new Feedback();
        BeanUtil.copyProperties(feedbackRequestVO, feedback);
        Example example = new Example(Feedback.class);
        example.createCriteria().andEqualTo("version", feedback.getVersion()).andEqualTo("code", feedback.getCode());
        feedback.setVersion(feedback.getVersion() + 1);
        int result = feebackMapper.updateByExampleSelective(feedback, example);
        if (result == 0) {
            throw new BusinessErrorException("反馈更新失败");
        }
    }

    @Override
    public void delete(String id) throws Exception {
        //TODO: 业务逻辑
        int result = feebackMapper.deleteByPrimaryKey(id);
        if (result == 0) {
            throw new BusinessErrorException("反馈删除失败");
        }
    }

    public Map<String, Object> historyList(String eventCode, String dispatchCode, int pageNo, int pageSize) {
        HashMap<String, Object> map = new HashMap<>(10);
        Example example = new Example(Feedback.class);
        example.createCriteria().andEqualTo("stat", 1).andEqualTo("dispatchCode", dispatchCode).andEqualTo("eventCode", eventCode);
        if (pageNo != 0 && pageSize != 0) {
            PageHelper.startPage(pageNo, pageSize);
            PageInfo<Feedback> pageInfo = new PageInfo<>(feebackMapper.selectByExample(example));
            map.put("list", pageInfo);
            map.put("total", pageInfo.getTotal());
            map.put("pageSize", pageInfo.getPageSize());
            map.put("pageNo", pageInfo.getPageNum());
        } else {
            List<Feedback> feedbacks = feebackMapper.selectByExample(example);
            map.put("list", feedbacks);
            map.put("total", feedbacks.size());
        }
        return map;
    }

    @Override
    public Feedback selectByCode(String code) throws Exception {
        Example example = new Example(Feedback.class);
        example.createCriteria().andEqualTo("code", code);
        return Optional.ofNullable(feebackMapper.selectOneByExample(example)).orElseThrow(() -> new BusinessErrorException("找不到该反馈信息，反馈编码为：" + code));
    }

    @Override
    public Map<String, Object> selectByCondition(FeedbackCondition conditions) throws Exception {
        HashMap<String, Object> map = new HashMap<>(10);
        Example example = getExample(conditions);
        if (conditions.getIsExport()) {
            List<Feedback> feedbackList = feebackMapper.selectByExample(example);
            List<String> headers = conditions.getHeaders();
            JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(feedbackList));
            String fileInfo = new ExeclUtil().exportExecl(headers,jsonArray,"F:\\");
            map.put("fileInfo", fileInfo);
        }else {
            if (conditions.getPageNo() != 0 && conditions.getPageSize() != 0) {
                PageHelper.startPage(conditions.getPageNo(), conditions.getPageSize());
                PageInfo<Feedback> pageInfo = new PageInfo<>(feebackMapper.selectByExample(example));
                map.put("list", pageInfo);
                map.put("total", pageInfo.getTotal());
                map.put("pageSize", pageInfo.getPageSize());
                map.put("pageNo", pageInfo.getPageNum());
            } else {
                List<Feedback> feedbacks = feebackMapper.selectByExample(example);
                map.put("list", feedbacks);
                map.put("total", feedbacks.size());
            }
        }
        return map;
    }

    String getDetailMsg(String feedbackDept, String feedbackOperator, String eventCode, String dispatchCode) {

        LocalDateTime todayDate = LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return "【" +
            feedbackDept +
            "】的【" +
            feedbackOperator +
            "】于【" +
            dtf.format(todayDate) +
            "】对事件【" +
            eventCode +
            "】的派单" +
            "【" +
            dispatchCode +
            "】进行了反馈。";
    }

    Example getExample(FeedbackCondition conditions) {
        Example example = new Example(Feedback.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(conditions.getEventCode())) {
            criteria.andEqualTo("eventCode", conditions.getEventCode());
        }

        if (StringUtils.isNotBlank(conditions.getDispatchCode())) {
            criteria.andEqualTo("dispatchCode", conditions.getDispatchCode());
        }
        example.setOrderByClause("'createTime' desc, 'modifyTime' desc");
        return example;
    }
}
